package vip.zhenzicheng.nettybasic.echo;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.AllArgsConstructor;

import java.net.InetSocketAddress;
import java.util.logging.Logger;

/**
 * 基于Netty的服务器
 *
 * @author zhenzicheng
 * @date 2022-06-06 19:52
 */
@AllArgsConstructor
public class EchoServer {

  private static final Logger LOG = Logger.getLogger(EchoServer.class.getSimpleName());

  private final int port;

  public static void main(String[] args) throws InterruptedException {
    int port = 9999;
    EchoServer echoServer = new EchoServer(port);
    LOG.info("服务器即将启动");
    echoServer.start();
    LOG.info("服务器关闭");
  }

  public void start() throws InterruptedException {
    // 线程组
    EventLoopGroup group = new NioEventLoopGroup();
    try {
      // 服务端启动必备
      ServerBootstrap bootstrap = new ServerBootstrap();

      bootstrap.group(group) // 将启动程序与线程组绑定
          .channel(NioServerSocketChannel.class) // 指定通讯模式
          .localAddress(new InetSocketAddress(port)) //
          // 因为NioServerSocketChannel只负责监听端口
          // 所以需要将数据流转在子SocketChannel上，设置childHandler
          .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel socketChannel) throws Exception {
              socketChannel.pipeline()
                  .addLast(new EchoServerHandler()); // 添加自定义的Handler
            }
          });
      // 异步绑定到服务器，sync()会阻塞直到完成
      ChannelFuture future = bootstrap.bind().sync();
      // 阻塞当前线程，直到服务器的 ServerChannel 被关闭
      future.channel().closeFuture().sync();

    } finally {
      group.shutdownGracefully().sync();
    }

  }


}
